<!--
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- [START picker_html] -->
<!DOCTYPE html>
<html>
  <head>
    <link
      rel="stylesheet"
      href="https://ssl.gstatic.com/docs/script/css/add-ons.css"
    />
    <style>
      #result {
        display: flex;
        flex-direction: column;
        gap: 0.25em;
      }

      pre {
        font-size: x-small;
        max-height: 25vh;
        overflow-y: scroll;
        background: #eeeeee;
        padding: 1em;
        border: 1px solid #cccccc;
      }
    </style>
    <script>
      // TODO: Replace the value for DEVELOPER_KEY with the API key obtained
      // from the Google Developers Console.
      const DEVELOPER_KEY = "AIza...";
      // TODO: Replace the value for CLOUD_PROJECT_NUMBER with the project
      // number obtained from the Google Developers Console.
      const CLOUD_PROJECT_NUMBER = "1234567890";

      let pickerApiLoaded = false;
      let oauthToken;

      /**
       * Loads the Google Picker API.
       */
      function onApiLoad() {
        gapi.load("picker", {
          callback: function () {
            pickerApiLoaded = true;
          },
        });
      }

      /**
       * Gets the user's OAuth 2.0 access token from the server-side script so that
       * it can be passed to Picker. This technique keeps Picker from needing to
       * show its own authorization dialog, but is only possible if the OAuth scope
       * that Picker needs is available in Apps Script. Otherwise, your Picker code
       * will need to declare its own OAuth scopes.
       */
      function getOAuthToken() {
        google.script.run
          .withSuccessHandler((token) => {
            oauthToken = token;
            createPicker(token);
          })
          .withFailureHandler(showError)
          .getOAuthToken();
      }

      /**
       * Creates a Picker that can access the user's spreadsheets. This function
       * uses advanced options to hide the Picker's left navigation panel and
       * default title bar.
       *
       * @param {string} token An OAuth 2.0 access token that lets Picker access the
       *     file type specified in the addView call.
       */
      function createPicker(token) {
        document.getElementById("result").innerHTML = "";

        if (pickerApiLoaded && token) {
          const picker = new google.picker.PickerBuilder()
            // Instruct Picker to display only spreadsheets in Drive. For other
            // views, see https://developers.google.com/picker/reference/picker.viewid
            .addView(
              new google.picker.DocsView(
                google.picker.ViewId.SPREADSHEETS
              ).setOwnedByMe(true)
            )
            // Hide the navigation panel so that Picker fills more of the dialog.
            .enableFeature(google.picker.Feature.NAV_HIDDEN)
            // Hide the title bar since an Apps Script dialog already has a title.
            .hideTitleBar()
            .setOAuthToken(token)
            .setDeveloperKey(DEVELOPER_KEY)
            .setAppId(CLOUD_PROJECT_NUMBER)
            .setCallback(pickerCallback)
            .setOrigin(google.script.host.origin)
            .build();
          picker.setVisible(true);
        } else {
          showError("Unable to load the file picker.");
        }
      }

      /**
       * @typedef {Object} PickerResponse
       * @property {string} action
       * @property {PickerDocument[]} docs
       */

      /**
       * @typedef {Object} PickerDocument
       * @property {string} id
       * @property {string} name
       * @property {string} mimeType
       * @property {string} url
       * @property {string} lastEditedUtc
       */

      /**
       * A callback function that extracts the chosen document's metadata from the
       * response object. For details on the response object, see
       * https://developers.google.com/picker/reference/picker.responseobject
       *
       * @param {PickerResponse} data The response object.
       */
      function pickerCallback(data) {
        const action = data[google.picker.Response.ACTION];
        if (action == google.picker.Action.PICKED) {
          handlePicked(data);
        } else if (action == google.picker.Action.CANCEL) {
          document.getElementById("result").innerHTML = "Picker canceled.";
        }
      }

      /**
       * Handles `"PICKED"` responsed from the Google Picker.
       *
       * @param {PickerResponse} data The response object.
       */
      function handlePicked(data) {
        const doc = data[google.picker.Response.DOCUMENTS][0];
        const id = doc[google.picker.Document.ID];

        google.script.run
          .withSuccessHandler((driveFilesGetResponse) => {
            // Render the response from Picker and the Drive.Files.Get API.
            const resultElement = document.getElementById("result");
            resultElement.innerHTML = "";

            for (const response of [
              {
                title: "Picker response",
                content: JSON.stringify(data, null, 2),
              },
              {
                title: "Drive.Files.Get response",
                content: JSON.stringify(driveFilesGetResponse, null, 2),
              },
            ]) {
              const titleElement = document.createElement("h3");
              titleElement.appendChild(document.createTextNode(response.title));
              resultElement.appendChild(titleElement);

              const contentElement = document.createElement("pre");
              contentElement.appendChild(
                document.createTextNode(response.content)
              );
              resultElement.appendChild(contentElement);
            }
          })
          .withFailureHandler(showError)
          .getFile(data[google.picker.Response.DOCUMENTS][0].id);
      }

      /**
       * Displays an error message within the #result element.
       *
       * @param {string} message The error message to display.
       */
      function showError(message) {
        document.getElementById("result").innerHTML = "Error: " + message;
      }
    </script>
  </head>

  <body>
    <div>
      <button onclick="getOAuthToken()">Select a file</button>
      <div id="result"></div>
    </div>
    <script src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
  </body>
</html>
<!-- [END picker_html] -->
